<template>
  <div class="device-detail-analysis">
    <!-- 设备区域选择器、事件分析按钮和设备状态网格 -->
    <el-card shadow="never" class="rounded-lg mb-4">
      <!-- 返回按钮 -->
      <div class="flex items-center mb-4">
        <el-button type="text" @click="handleBack" class="!p-0">
          <el-icon class="text-18px text-#606266 hover:text-#409eff transition-colors">
            <ArrowLeft/>
          </el-icon>
        </el-button>
      </div>
      <div class="flex items-center gap-2 mb-4 text-14px">
        <div class="font-bold text-#606266 mr-2">甲醇制氢装置</div>
        <div class="w-[91px] h-[35px] bg-[#7FFF88] rounded text-#222222 flex items-center justify-center">无报警</div>
        <div class="w-[91px] h-[35px] bg-[#FFD37F] rounded text-#222222 flex items-center justify-center">H/L</div>
        <div class="w-[91px] h-[35px] bg-[#FF7F7F] rounded text-#222222 flex items-center justify-center">HH/LL</div>
        <div class="w-[91px] h-[35px] bg-[#DC99FF] rounded text-#222222 flex items-center justify-center">连锁</div>
      </div>
      <el-divider/>
      <div class="flex items-center mb-4">
        <el-select v-model="selectedSectionId" placeholder="选择设备区域" class="!w-200px mr-5">
          <el-option
            v-for="section in deviceSections"
            :key="section.id"
            :label="section.title"
            :value="section.id"
          />
        </el-select>
        <el-button type="primary" @click="handleEventAnalysis">
          <el-icon class="mr-1">
            <DataAnalysis/>
          </el-icon>
          事件分析
        </el-button>
      </div>

      <!-- 当前设备区域状态网格 -->
      <div class="grid grid-cols-15 gap-2">
        <div
          v-for="(item, index) in currentDevices"
          :key="`${currentSection?.id}-${index}`"
          :class="getTagClass(item.status)"
          class="px-3 py-2 rounded text-center text-sm font-medium !text-#222222"
        >
          {{ item.code }}
        </div>
      </div>
    </el-card>

    <!-- 流程图 -->
    <div class="logicflow-container" ref="logicFlowRef"></div>

    <!-- 报警节点趋势弹窗 -->
    <el-dialog
      v-model="showTrendDialog"
      width="520px"
      :show-close="true"
      class="alarm-trend-dialog"
      append-to-body
    >
      <template #header>
        <div class="flex items-start justify-between w-full">
          <div class="flex flex-col">
            <div class="text-14px text-#606266">{{ trendInfo.title }}</div>
            <div>
              <span class="text-24px font-700 text-#2F7BFF">{{ trendInfo.value }}</span>
              <span class="ml-2 text-14px text-#6B7280">{{ trendInfo.unit }}</span>
            </div>
          </div>
        </div>
      </template>
      <v-chart class="w-full h-[260px]" :option="trendOption" autoresize/>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {computed, onMounted, onUnmounted, reactive, ref, watch} from 'vue';
import {ElMessage} from 'element-plus';
import {ArrowLeft, DataAnalysis} from '@element-plus/icons-vue';
import LogicFlow, {
  type EdgeConfig,
  HtmlNode,
  HtmlNodeModel,
  type NodeConfig,
  PolylineEdge,
  PolylineEdgeModel
} from '@logicflow/core';
import '@logicflow/core/dist/index.css';

interface DeviceItem {
  id: number;
  code: string;
  systemLocation: string;
  status: string;
  alarmTime?: string;
  description?: string;
}

interface DeviceSection {
  id: string;
  title: string;
  devices: DeviceItem[];
}

const props = defineProps<{
  selectedDevice: DeviceItem | null;
  selectedSection: DeviceSection | null;
  deviceSections: DeviceSection[];
}>();

const emit = defineEmits<{
  back: [];
}>();

const selectedSectionId = ref(props.selectedSection?.id || props.deviceSections[0]?.id || '');
const logicFlowRef = ref<HTMLDivElement | null>(null);
let lf: LogicFlow | null = null;

// 事件分析状态
const isAnalyzing = ref(false);

// 趋势弹窗相关
const showTrendDialog = ref(false);
const trendInfo = reactive({
  title: '',
  value: '',
  unit: ''
});
const trendOption = computed(() => {
  // 模拟数据，可后续替换为接口数据
  const xAxis = [1, 2, 3, 4, 5, 6, 7];
  const realtime = [80, 60, 70, 95, 85, 55, 65];
  const high = [40, 70, 100, 120, 90, 60, 85];
  const low = [30, 55, 65, 40, 45, 60, 100];
  return {
    grid: {left: 30, right: 20, top: 10, bottom: 25},
    tooltip: {trigger: 'axis'},
    legend: {
      right: 10,
      top: 0,
      icon: 'circle',
      textStyle: {color: '#6B7280'},
      data: ['实时', '高报', '低报']
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: xAxis,
      axisLine: {lineStyle: {color: '#8CA3C7'}},
      axisLabel: {color: '#6B7280'},
      splitLine: {show: false}
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 120,
      axisLine: {show: false},
      axisLabel: {color: '#6B7280'},
      splitLine: {lineStyle: {color: '#D5E2F2', type: 'dashed'}}
    },
    series: [
      {
        name: '实时',
        type: 'line',
        smooth: true,
        symbol: 'none',
        lineStyle: {color: '#3AA0FF', width: 2},
        areaStyle: {
          color: {
            type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
            colorStops: [
              {offset: 0, color: 'rgba(58,160,255,0.35)'},
              {offset: 1, color: 'rgba(58,160,255,0.05)'}
            ]
          }
        },
        data: realtime
      },
      {
        name: '高报',
        type: 'line',
        smooth: true,
        symbol: 'none',
        lineStyle: {color: '#FF6B6B', width: 2},
        areaStyle: {
          color: {
            type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
            colorStops: [
              {offset: 0, color: 'rgba(255,107,107,0.35)'},
              {offset: 1, color: 'rgba(255,107,107,0.05)'}
            ]
          }
        },
        data: high
      },
      {
        name: '低报',
        type: 'line',
        smooth: true,
        symbol: 'none',
        lineStyle: {color: '#34D399', width: 2},
        areaStyle: {
          color: {
            type: 'linear', x: 0, y: 0, x2: 0, y2: 1,
            colorStops: [
              {offset: 0, color: 'rgba(52,211,153,0.35)'},
              {offset: 1, color: 'rgba(52,211,153,0.05)'}
            ]
          }
        },
        data: low
      }
    ]
  } as any;
});

// 当前选中的设备区域
const currentSection = computed(() => {
  return props.deviceSections.find(section => section.id === selectedSectionId.value);
});

// 当前区域的设备列表
const currentDevices = computed(() => {
  return currentSection.value?.devices || [];
});

// 获取标签样式类
const getTagClass = (status: string) => {
  switch (status) {
    case 'normal':
      return 'bg-#7FFF88';
    case 'warning':
      return 'bg-#FFD37F';
    case 'danger':
      return 'bg-#FF7F7F';
    default:
      return 'bg-#7FFF88';
  }
};

// 返回按钮处理
const handleBack = () => {
  emit('back');
};

// 事件分析按钮处理
const handleEventAnalysis = () => {
  isAnalyzing.value = !isAnalyzing.value;
  if (isAnalyzing.value) {
    ElMessage.success('已开启事件分析');
  } else {
    ElMessage.info('已关闭事件分析');
  }
  // 重新渲染流程图
  renderFlow();
};

// 流程图数据
type FlowTreeNode = {
  title: string;
  content: string;
  device: string | number;
  value: string | number;
  isWarn: number | boolean;
  children?: FlowTreeNode[];
};

const flowData: FlowTreeNode = {
  title: '回流系统停止',
  content: '人员因素',
  device: '',
  value: '',
  isWarn: 0,
  children: [
    {
      title: '过高温度',
      content: '过高温度',
      device: 'FIC1207',
      value: '186',
      isWarn: 1,
      children: [
        {
          title: '外部错误',
          content: '阀门误关',
          device: 'FIC1207',
          value: '186',
          isWarn: 1
        },
        {
          title: '人员因素',
          content: '巡检遗漏',
          device: '',
          value: '',
          isWarn: 0,
          children: [
            {
              title: '报警联锁',
              content: '紧急切断',
              device: '',
              value: '',
              isWarn: 1,
              children: [
                {
                  title: '后果评估',
                  content: '影响范围扩大',
                  device: '',
                  value: '',
                  isWarn: 0
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};

// LogicFlow 节点和边的生成（横向布局）
type FlowLayoutOptions = {
  nodeWidth?: number;
  hGap?: number;
  vGap?: number;
  left?: number;
  top?: number;
  orientation?: 'vertical' | 'horizontal';
};

function buildFlowFromTree(root: FlowTreeNode, opts: FlowLayoutOptions = {}) {
  const hGap = opts.hGap ?? 240; // 层间距
  const vGap = opts.vGap ?? 160; // 叶子方向间距
  const left = opts.left ?? 120; // 左侧起点
  const top = opts.top ?? 0; // 顶部起点
  const orientation = opts.orientation ?? 'horizontal';

  // 计算叶子数
  const leafCountMap = new Map<FlowTreeNode, number>();
  const calcLeaves = (n: FlowTreeNode): number => {
    if (!n.children || n.children.length === 0) {
      leafCountMap.set(n, 1);
      return 1;
    }
    const sum = n.children.map(calcLeaves).reduce((a, b) => a + b, 0);
    leafCountMap.set(n, sum);
    return sum;
  };
  calcLeaves(root);

  // 生成 id
  let nodeAutoId = 1;
  let edgeAutoId = 1;
  const idMap = new Map<FlowTreeNode, string>();

  const nodes: any[] = [];
  const edges: EdgeConfig[] = [];

  // 横向布局：层沿 x 轴，叶子扩展沿 y 轴
  const assignHorizontal = (n: FlowTreeNode, depth: number, startTop: number, parent?: FlowTreeNode) => {
    const leaves = leafCountMap.get(n) || 1;
    const height = leaves * vGap;
    const x = left + depth * hGap;
    const y = startTop + height / 2;

    const id = `n${nodeAutoId++}`;
    idMap.set(n, id);

    nodes.push({id, type: 'flow-node', x, y, text: {value: {...n}}});

    if (parent) {
      const pid = idMap.get(parent)!;
      edges.push({id: `e${edgeAutoId++}`, type: 'flow-edge', sourceNodeId: pid, targetNodeId: id});
    }

    if (n.children && n.children.length) {
      let curTop = startTop;
      for (const child of n.children) {
        const cLeaves = leafCountMap.get(child) || 1;
        const cHeight = cLeaves * vGap;
        assignHorizontal(child, depth + 1, curTop, n);
        curTop += cHeight;
      }
    }
  };

  assignHorizontal(root, 0, top);
  return {nodes, edges};
}

// 自定义节点视图
class FlowNodeView extends HtmlNode {
  setHtml(rootEl: SVGForeignObjectElement) {
    const modelAny: any = this.props.model as any;
    const raw = (modelAny?.properties?.label ?? {}) as any;
    const isWarn = raw?.isWarn === 1 || raw?.isWarn === '1' || raw?.isWarn === true;

    const escapeHtml = (s: unknown) =>
      String(s ?? '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');

    const title = String(raw?.title ?? '--');
    const device = String(raw?.device ?? '--');
    const value = String(raw?.value ?? '--');

    const safeLabel = `
        <div class="lf-flow-node__title">${escapeHtml(title)}</div>
        <div class="lf-flow-node__meta">
            <span>${escapeHtml(device)}</span>
            <span class="lf-flow-node__divider">|</span>
            <span>${escapeHtml(value)}</span>
        </div>
      `;

    // 根据分析状态和报警状态选择样式类
    let nodeClass = 'lf-flow-node';
    if (isAnalyzing.value) {
      // 事件分析模式：报警节点用警告样式，非报警节点用灰色样式
      nodeClass += isWarn ? ' lf-flow-node--warn' : ' lf-flow-node--gray';
    } else {
      // 普通模式：只有报警节点用警告样式
      nodeClass += isWarn ? ' lf-flow-node--warn' : '';
    }

    // 直接通过 innerHTML 设置整个节点 HTML
    rootEl.innerHTML = `
    <div class="${nodeClass}" style="width:100%;height:100%">${safeLabel}</div>
    `;

    // 绑定点击事件，保持交互能力
    const el = rootEl.querySelector('.lf-flow-node') as HTMLElement | null;
    if (el) {
      el.addEventListener('click', () => {
        try {
          const {graphModel, model} = this.props as any;
          graphModel?.eventCenter?.emit?.('custom:flow-node-click', model);
        } catch {
        }
      });
    }
  }
}

// 自定义节点模型
class FlowNodeModel extends HtmlNodeModel {
  setAttributes() {
    super.setAttributes();
    this.width = 180;
    this.height = 90;
  }
}

// 自定义边模型
class FlowEdgeModel extends PolylineEdgeModel {
  getEdgeStyle() {
    const style = super.getEdgeStyle();
    return {
      ...style,
      stroke: '#37A8FF',
      strokeDasharray: '6 4',
      strokeWidth: 1.4
    };
  }
}

class FlowEdgeDangerModel extends PolylineEdgeModel {
  getEdgeStyle() {
    const style = super.getEdgeStyle();
    return {
      ...style,
      stroke: '#FF3737',
      strokeDasharray: '6 4',
      strokeWidth: 1.4
    };
  }
}

class FlowEdgeGrayModel extends PolylineEdgeModel {
  getEdgeStyle() {
    const style = super.getEdgeStyle();
    return {
      ...style,
      stroke: '#CCCCCC',
      strokeDasharray: '6 4',
      strokeWidth: 1.4
    };
  }
}

// 初始化LogicFlow
function initLogicFlow() {
  if (!logicFlowRef.value) return;

  lf?.destroy();
  lf = new LogicFlow({
    container: logicFlowRef.value,
    grid: false,
    adjustNodePosition: false,
    stopZoomGraph: false,
    stopScrollGraph: false,
    stopMoveGraph: false,
    background: {
      backgroundColor: '#fff'
    },
    hoverOutline: false,
    nodeSelectedOutline: false,
    edgeSelectedOutline: false,
    adjustEdge: false,
    nodeTextEdit: false,
    isSilentMode: true,
    animation: true,
  });

  lf.register({
    type: 'flow-node',
    view: FlowNodeView,
    model: FlowNodeModel
  });

  lf.register({
    type: 'flow-edge',
    view: PolylineEdge,
    model: FlowEdgeModel
  });

  lf.register({
    type: 'flow-edge-danger',
    view: PolylineEdge,
    model: FlowEdgeDangerModel
  });

  lf.register({
    type: 'flow-edge-gray',
    view: PolylineEdge,
    model: FlowEdgeGrayModel
  });

  // Listen to custom event from HtmlNode view
  lf.on('custom:flow-node-click', (model: any) => {
    try {
      // 仅在事件分析模式下，且点击报警节点时弹窗
      if (!isAnalyzing.value) return;
      const label: any = model?.properties?.label || {};
      const isWarn = label?.isWarn === 1 || label?.isWarn === '1' || label?.isWarn === true;
      if (!isWarn) return;

      trendInfo.title = String(label?.title ?? '');
      trendInfo.value = String(label?.value ?? '');
      trendInfo.unit = String(label?.unit ?? '');
      showTrendDialog.value = true;
    } catch {
      // ignore
    }
  });

  renderFlow();
}

// 渲染流程图
function renderFlow() {
  if (!lf) return;

  lf.clearData();
  const flow = buildFlowFromTree(flowData, {
    // 横向布局参数
    nodeWidth: 180,
    hGap: 240,
    vGap: 160,
    left: 120,
    top: 50,
    orientation: 'horizontal'
  });

  const rawNodes = flow.nodes as any[];
  const nodes: NodeConfig[] = rawNodes.map((n) => {
    const copy: any = {...n, properties: {...(n as any).properties}};
    copy.properties.label = (n as any)?.text?.value ?? copy?.properties?.label ?? '';
    if (copy.text) delete copy.text;
    return copy as NodeConfig;
  });

  // 根据节点的 isWarn 和分析状态动态生成连线类型
  const baseEdges = flow.edges || [];
  const getTargetWarn = (targetId: string) => {
    const target = rawNodes.find((n: any) => n.id === targetId);
    const v = (target as any)?.text?.value?.isWarn;
    return v === 1 || v === '1' || v === true;
  };

  const edges: EdgeConfig[] = baseEdges.map((e) => {
    const targetIsWarn = getTargetWarn(e.targetNodeId);

    if (isAnalyzing.value) {
      // 事件分析模式：指向报警节点用危险连线，指向非报警节点用灰色连线
      return {
        ...e,
        type: targetIsWarn ? 'flow-edge-danger' : 'flow-edge-gray'
      };
    } else {
      // 普通模式：指向报警节点用危险连线，其他用普通连线
      return {
        ...e,
        type: targetIsWarn ? 'flow-edge-danger' : 'flow-edge'
      };
    }
  });

  lf.render({nodes, edges});
}

// 监听选中区域变化
watch(selectedSectionId, () => {
  // 这里可以根据不同区域加载不同的流程图数据
  renderFlow();
});

onMounted(() => {
  setTimeout(() => {
    initLogicFlow();
  }, 100);
});

onUnmounted(() => {
  lf?.destroy();
});
</script>

<style lang="scss" scoped>
.device-detail-analysis {
  .logicflow-container {
    width: 100%;
    height: 500px;
  }
}

// LogicFlow 组件样式
:deep(.lf-flow-node) {
  padding: 12px 15px;
  background: transparent url('@/assets/images/alarm-flow-box-act.png') no-repeat center / 100% 100%;
  color: #ffffff;
  line-height: 1.4;
  text-align: left;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  white-space: normal;
}

// 报警节点使用警示边框背景
:deep(.lf-flow-node--warn) {
  background-image: url('@/assets/images/alarm-flow-box-act.png') !important;
}

// 灰色节点使用灰色背景
:deep(.lf-flow-node--gray) {
  background-image: url('@/assets/images/alarm-flow-box-gray.png') !important;
}

:deep(.lf-flow-node__inner) {
  white-space: pre-line;
}

// 新的节点内部排版样式
:deep(.lf-flow-node__title) {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 2px;
}

:deep(.lf-flow-node__meta) {
  display: flex;
  justify-content: space-between;
  align-items: center;
  line-height: 1.2;
  margin-top: 25px;
  font-size: 14px;
  color: #222;
}

:deep(.lf-flow-node__divider) {
  color: #999;
  margin: 0 4px;
}

:deep(.lf-flow-node__bars) {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  height: 12px;
}

:deep(.lf-graph) {
  background: transparent !important;
}

// 弹窗样式微调
:deep(.alarm-trend-dialog) {
  .el-dialog__header {
    margin-right: 0;
    padding-bottom: 0;
  }

  .el-dialog__body {
    padding-top: 8px;
  }
}
</style>
